const router = require('koa-router')()
const { models } = require('../../model')
const { convertToObjectId } = require('../../utils/db')
const { cloneDeep } = require('lodash')
const UserController = require('../../controller/user')
const userController = new UserController()
const { process, initKmSpace, getKmSpace } = require('../../service/km')
const { ObjectID } = require('mongodb')

const KM_PUBLIC_ATTRS = {
  title: 1,
  draft: 1,
  content: 1,
  parentId: 1,
  createUserId: 1,
  updateUserId: 1,
  statistics: 1,
  type: 1,
  level: 1,
  seq: 1,
  status: 1,
  tags: 1,
  createWay: 1,
  contentForm: 1,
  fromCid: 1,
  kmSpaceId: 1
}

router.use(userController.userFilter())

// 列表
router.get('/list', async function (ctx) {
  const query = ctx.query
  const findQuery = {}
  // query.sort
  if (query.sorts === undefined || query.sorts === '') {
    query.sorts = { createdAt: -1 }
  } else {
    query.sorts = JSON.parse(query.sorts)
  }
  findQuery.status = 6
  findQuery.kmSpaceId = query.kmSpaceId
  const attrs = cloneDeep(KM_PUBLIC_ATTRS)
  delete attrs.content
  const docs = await models.Article
    .find(findQuery)
    .project({ title: 1, createdAt: 1, statistics: 1 })
    .sort(query.sorts)
    .limit(10)
    .toArray()
  docs.forEach(e => {
    e._id = e._id.toString()
  })
  ctx.wrapper.succ(docs)
})

// 列表
router.get('/menu', async function (ctx) {
  const query = ctx.query
  const findQuery = {}
  findQuery.kmSpaceId = ObjectID(query.kmSpaceId)
  let docs = await models.Article
    .find(findQuery)
    .project({
      title: 1,
      parentId: 1,
      type: 1,
      level: 1,
      seq: 1,
      status: 1,
      kmSpaceId: 1,
      contentForm: 1,
      createWay: 1,
      fromCid: 1,
      createUserId: 1
    })
    .toArray()
  docs.forEach(doc => {
    doc.seq ? doc.seq = parseInt(doc.seq) : doc.seq = -1
    if (doc.contentForm === 2) {
      const doc1 = docs.filter(e => e._id.toString() === doc.fromCid.toString())
      doc.title = doc1[0].title
    }
    if (doc.title === undefined || doc.title === '') doc.title = '未命名文档'
    if (doc.status === 8) {
      doc.title = '已下线·' + doc.title
    } else if (doc.status === 1) {
      doc.title = '未发布·' + doc.title
    }
  })
  docs = docs.filter(doc => {
    // 没有_user（没有登录）或_user角色不是管理员，看6
    if (ctx._user === undefined ||
      (ctx._user.role !== 0 && doc.createUserId.toString() !== ctx._user._id.toString()) ||
      parseInt(query.status) === 6) {
      return doc.status === 6
    } else {
      return true
    }
  })

  // query.sort
  // if (query.sorts === undefined || query.sorts === '') {
  //     query.sorts = {seq: 1}
  // } else {
  //     query.sorts = JSON.parse(query.sorts)
  // }
  docs.sort(function (a, b) { return a.seq - b.seq })

  // 转为树结构
  const array2Tree = (data, pid, level, parentPrefix) => {
    level++
    let showSeq = 1
    const res = []
    data.forEach(item => {
      if (item.parentId === pid) {
        item.level = level
        item.showSeq = showSeq++
        if (parentPrefix === '') {
          item.prefix = item.seq
        } else {
          item.prefix = parentPrefix + '.' + item.seq
        }
        // item.title = item.prefix + ' ' + item.title
        // item.title = item.showSeq + ' ' + item.title
        const itemChildren = array2Tree(data, item._id.toString(), level, item.prefix)
        item.children = itemChildren
        // q-menu不允许有相同的id，故生成新id，因为1个标签会有多个父标签
        // item.menuId = ++i
        res.push(item)
      }
    })
    return res
  }
  const docsTree = array2Tree(docs, '', 0, '')
  // 对于Topic下标签的不返回
  // docsTree = docsTree.filter(e => e.name !== 'Topic')
  ctx.wrapper.succ(docsTree)
})

// 文章内容
router.get('/article', async function (ctx) {
    const query = ctx.query
    const findQuery = {}

    if (query.id) {
        findQuery._id = convertToObjectId(query.id)
    } else {
        findQuery.isHomepage = 1
    }
    //
    const doc = await models.Article
        .find(findQuery)
        .project(KM_PUBLIC_ATTRS)
        .limit(1)
        .toArray()

    // 若doc是引用类型，需要再把引用的内容取出
    const fromDoc = {}
    if (doc[0].contentForm === 2) {
        const fromDoc = await models.Article
            .findOne({ _id: ObjectID(doc[0].fromCid) })
        doc[0].title = fromDoc.title
        doc[0].content = fromDoc.content
        doc[0].statistics = fromDoc.statistics
        doc[0].tags = fromDoc.tags
    }

    if (doc[0].status !== 6 || (fromDoc.status && fromDoc.status !== 6)) {
        // 文章不为发布状态时
        if (!ctx._user) {
            // 非登录用户不可查看
            return ctx.wrapper.succ({})
        }
        if (ctx._user.role !== 0 && ctx._user._id.toString() !== doc[0].createUserId.toString()) {
            // 非管理员和作者本人，不可查看
            return ctx.wrapper.succ({})
        }
    }

    process(ctx, doc[0])

    // 获取其各级父级id
    doc[0].parents = await getParents(doc[0].parentId)

    ctx.wrapper.succ(doc[0])
})

async function getParents (pid) {
  let parents = []
  if (pid === undefined || pid === '') return parents
  let doc = await models.Article
    .find({ _id: convertToObjectId(pid) })
    .project({ title: 1, parentId: 1 })
    .limit(1)
    .toArray()
  if (doc.length > 0) {
    doc = doc[0]
    parents.push(doc)
    if (doc.parentId !== '') {
      // 若有父级，合并其父级
      parents = parents.concat(await getParents(doc.parentId))
    }
  }
  return parents
}

router.post('/create', async function (ctx) {
  // let user = ctx._user || ctx._tUser;
  // 创建公共空间的
  const params = ctx.request.body
  const doc = {
    createUserId: ctx._user._id,
    status: 1,
    title: params.title,
    draft: params.draft,
    content: params.content,
    type: params.type,
    createWay: 1,
    contentForm: 1,
    statistics: { shows: 0, reads: 0, likes: 0, collects: 0, shares: 0, votes: 0 },
    parentId: params.parentId,
    kmSpaceId: ObjectID(params.kmSpaceId)
  }

  const ret = await models.Article.insertOne(doc)
  return ctx.wrapper.succ({ _id: ret.insertedId })
})

router.post('/clone', async function (ctx) {
  let kmSpaceId = ctx._user.kmSpaceId
  if (!kmSpaceId) {
    await initKmSpace(ctx._user._id)
    const doc = await getKmSpace()
    kmSpaceId = doc._id
  }
  const doc = {
    createUserId: ctx._user._id,
    createWay: 2,
    status: 1,
    contentForm: 1,
    statistics: { shows: 0, reads: 0, likes: 0, collects: 0, shares: 0, votes: 0 },
    kmSpaceId: kmSpaceId
  }
  const params = ctx.request.body
  let fromDoc = await models.Article
    .find({ _id: convertToObjectId(params.cid) })
    .project({})
    .limit(1)
    .toArray()
  fromDoc = fromDoc[0]
  doc.fromCid = fromDoc._id
  doc.title = fromDoc.title
  doc.content = fromDoc.content
  doc.tags = fromDoc.tags
  doc.type = fromDoc.type

  // let fromDoc = await models.Article
  //     .find({name: convertToObjectId(params.cid)})
  //     .project({})
  //     .limit(1)
  //     .toArray();
  // doc.parentId = '再创作'
  doc.parentId = ''

  const ret = await models.Article.insertOne(doc)
  return ctx.wrapper.succ({ _id: ret.insertedId })
})

router.post('/collect', async function (ctx) {
  // let user = ctx._user || ctx._tUser;
  // 创建公共空间的
  const params = ctx.request.body
  const doc = {
    createUserId: ctx._user._id,
    createWay: 3,
    status: 6,
    contentForm: 2,
    kmSpaceId: ctx._user.kmSpaceId,
    fromCid: ObjectID(params.cid)
  }

  // let fromDoc = await models.Article
  //     .find({name: convertToObjectId(params.cid)})
  //     .project({})
  //     .limit(1)
  //     .toArray();
  // doc.parentId = '再创作'
  doc.parentId = ''

  const ret = await models.Article.insertOne(doc)
  return ctx.wrapper.succ({ _id: ret.insertedId })
})

router.post('/update', async function (ctx) {
  const doc = ctx.request.body
  const doc1 = await models.Article.findOne({ _id: ObjectID(doc._id) })
  if (ctx._user.role !== 0 && ctx._user._id.toString() !== doc1.createUserId.toString()) { return ctx.wrapper.error('PERMISSION_ERROR', '无权限') }
  const _id = doc._id
  delete doc._id
  doc.updateUserId = ctx._user._id
  delete doc.user
  const ret = await models.Article.updateOne({
    _id: convertToObjectId(_id)
  }, {
    $set: doc
  }, { multi: false })
  return ctx.wrapper.succ(ret)
})

// 标签 - 获取所有 1/2/3 级标签
router.get('/tags', async function (ctx) {
  const tags = await models.Article.find({}).project({
    tags: 1
  }).sort({}).toArray()

  // 将 parentTags 数组解开来
  const set = new Set()
  tags.forEach(e => {
    if (e.tags && e.tags > 0) set.add(...e.tags)
  })

  ctx.wrapper.succ(set)
})

router.get('/ads', async function (ctx) {
  const query = ctx.query
  let findQuery = {}
  if (query.contentId) {
    findQuery.kmContentIds = {
      $in: [convertToObjectId(query.contentId)]
    }
    findQuery.status = 1
  } else {
    findQuery = { type: 2, status: 1 }
  }
  // TODO 符合条件的随机一条
  let doc = await models.Ads
    .find(findQuery)
    .project({})
    .limit(1)
    .toArray()

  // 没有符合的，以一定概率显示自己的广告
  if (doc.length === 0) {
    doc = await models.Ads
      .find({ type: 2, status: 1 })
      .project({})
      .limit(1)
      .toArray()
  }

  ctx.wrapper.succ(doc[0])
})

router.get('/spaces', async function (ctx) {
  const findQuery = {}
  findQuery.$or = [
    { type: 1, status: 1 },
    { userId: ctx._user ? ctx._user._id : '' }
  ]

  const docs = await models.KmSpace
    .find(findQuery)
    .project({})
    .toArray()

  ctx.wrapper.succ(docs)
})

module.exports = router
